home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ImageMagick / mogrify.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  36KB  |  1,024 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %              M   M   OOO    GGGG  RRRR   IIIII  FFFFF  Y   Y                %
  7. %              MM MM  O   O  G      R   R    I    F       Y Y                 %
  8. %              M M M  O   O  G GG   RRRRR    I    FFF      Y                  %
  9. %              M   M  O   O  G   G  R R      I    F        Y                  %
  10. %              M   M   OOO    GGG   R  R   IIIII  F        Y                  %
  11. %                                                                             %
  12. %                                                                             %
  13. %               Transmogrify an Image or Sequence of Images.                  %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                           Software Design                                   %
  18. %                             John Cristy                                     %
  19. %                            December 1992                                    %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1994 E. I. du Pont de Nemours & Company                          %
  23. %                                                                             %
  24. %  Permission to use, copy, modify, distribute, and sell this software and    %
  25. %  its documentation for any purpose is hereby granted without fee,           %
  26. %  provided that the above Copyright notice appear in all copies and that     %
  27. %  both that Copyright notice and this permission notice appear in            %
  28. %  supporting documentation, and that the name of E. I. du Pont de Nemours    %
  29. %  & Company not be used in advertising or publicity pertaining to            %
  30. %  distribution of the software without specific, written prior               %
  31. %  permission.  E. I. du Pont de Nemours & Company makes no representations   %
  32. %  about the suitability of this software for any purpose.  It is provided    %
  33. %  "as is" without express or implied warranty.                               %
  34. %                                                                             %
  35. %  E. I. du Pont de Nemours & Company disclaims all warranties with regard    %
  36. %  to this software, including all implied warranties of merchantability      %
  37. %  and fitness, in no event shall E. I. du Pont de Nemours & Company be       %
  38. %  liable for any special, indirect or consequential damages or any           %
  39. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  40. %  in an action of contract, negligence or other tortuous action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %  `Mogrify' applies one or more image transforms to an image or sequence of
  46. %   images and overwrites the original image.
  47. %
  48. %  The Mogrify program command syntax is:
  49. %
  50. %  Usage: mogrify [options ...] file [ [options ...] file ...]
  51. %
  52. %  Where options include:
  53. %    -border geometry     surround image with a border of color
  54. %    -clip geometry       preferred size and location of the clipped image
  55. %    -colormap filename   transform image colors to match this set of colors
  56. %    -colors value        preferred number of colors in the image
  57. %    -colorspace type     GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV
  58. %    -comment string      annotate image with comment
  59. %    -compress type       RunlengthEncoded or QEncoded
  60. %    -density geometry    vertical and horizontal density of the image
  61. %    -display server      obtain image or font from this X server
  62. %    -dither              apply Floyd/Steinberg error diffusion to image
  63. %    -enhance             apply a digital filter to enhance a noisy image
  64. %    -font name           X11 font for displaying text
  65. %    -gamma value         level of gamma correction
  66. %    -geometry geometry   preferred size of the image
  67. %    -interlace type      NONE, LINE, or PLANE
  68. %    -inverse             apply color inversion to image
  69. %    -label name          assign a label to an image
  70. %    -monochrome          transform image to black and white
  71. %    -noise               reduce noise with a noise peak elimination filter
  72. %    -normalize           transform image to span the full range of colors
  73. %    -page geometry       size and location of the Postscript page
  74. %    -quality value       JPEG quality setting
  75. %    -reflect             reverse image scanlines
  76. %    -roll geometry       roll an image vertically or horizontally
  77. %    -rotate degrees      apply Paeth rotation to the image
  78. %    -scale geometry      preferred size factors of the image
  79. %    -scene value         image scene number
  80. %    -shear geometry      slide one edge of the image along the X or Y axis
  81. %    -treedepth value     depth of the color classification tree
  82. %    -undercolor geometry control undercolor removal and black generation
  83. %    -verbose             print detailed information about the image
  84. %
  85. %  Change '-' to '+' in any option above to reverse its effect.  For
  86. %  example, specify +compress to store the image as uncompressed.
  87. %
  88. %  By default, the image format of `file' is determined by its magic
  89. %  number.  To specify a particular image format, precede the filename
  90. %  with an image format name and a colon (i.e. ps:image) or specify the
  91. %  image type as the filename suffix (i.e. image.ps).  Specify 'file' as
  92. %  '-' for standard input or output.
  93. %
  94. %
  95. */
  96.  
  97. /*
  98.   Include declarations.
  99. */
  100. #include "magick.h"
  101. #include "image.h"
  102. #include "X.h"
  103.  
  104. /*
  105. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  106. %                                                                             %
  107. %                                                                             %
  108. %                                                                             %
  109. %   U s a g e                                                                 %
  110. %                                                                             %
  111. %                                                                             %
  112. %                                                                             %
  113. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  114. %
  115. %  Function Usage displays the program command syntax.
  116. %
  117. %  The format of the Usage routine is:
  118. %
  119. %      Usage()
  120. %
  121. %
  122. */
  123. static void Usage()
  124. {
  125.   char
  126.     **p;
  127.  
  128.   static char
  129.     *options[]=
  130.     {
  131.       "-border geometry     surround image with a border of color",
  132.       "-clip geometry       preferred size and location of the clipped image",
  133.       "-colormap filename   transform image colors to match this set of colors",
  134.       "-colors value        preferred number of colors in the image",
  135.       "-colorspace type     GRAY, OHTA, RGB, XYZ, YCbCr, YIQ, or YUV",
  136.       "-comment string      annotate image with comment",
  137.       "-compress type       RunlengthEncoded or QEncoded",
  138.       "-density geometry    vertical and horizontal density of the image",
  139.       "-display server      obtain image or font from this X server",
  140.       "-dither              apply Floyd/Steinberg error diffusion to image",
  141.       "-enhance             apply a digital filter to enhance a noisy image",
  142.       "-font name           X11 font for displaying text",
  143.       "-gamma value         level of gamma correction",
  144.       "-geometry geometry   preferred size of the image",
  145.       "-interlace type      NONE, LINE, or PLANE",
  146.       "-inverse             apply color inversion to image",
  147.       "-label name          assign a label to an image",
  148.       "-monochrome          transform image to black and white",
  149.       "-noise               reduce noise with a noise peak elimination filter",
  150.       "-normalize           transform image to span the full range of colors",
  151.       "-page geometry       size and location of the Postscript page",
  152.       "-quality value       JPEG quality setting",
  153.       "-reflect             reflect the image scanlines",
  154.       "-roll geometry       roll an image vertically or horizontally",
  155.       "-rotate degrees      apply Paeth rotation to the image",
  156.       "-scale geometry      preferred size factors of the image",
  157.       "-scene number        image scene number",
  158.       "-shear geometry      slide one edge of the image along the X or Y axis",
  159.       "-treedepth value     depth of the color classification tree",
  160.       "-undercolor geometry control undercolor removal and black generation",
  161.       "-verbose             print detailed information about the image",
  162.       (char *) NULL
  163.     };
  164.   (void) fprintf(stderr,
  165.     "Usage: %s [-options ...] file [ [-options ...] file ...]\n",client_name);
  166.   (void) fprintf(stderr,"\nWhere options include: \n");
  167.   for (p=options; *p != (char *) NULL; p++)
  168.     (void) fprintf(stderr,"  %s\n",*p);
  169.   (void) fprintf(stderr,
  170.     "\nChange '-' to '+' in any option above to reverse its effect.  For\n");
  171.   (void) fprintf(stderr,
  172.     "example, specify +compress to store the image as uncompressed.\n");
  173.   (void) fprintf(stderr,
  174.     "\nBy default, the image format of `file' is determined by its magic\n");
  175.   (void) fprintf(stderr,
  176.     "number.  To specify a particular image format, precede the filename\n");
  177.   (void) fprintf(stderr,
  178.     "with an image format name and a colon (i.e. ps:image) or specify the\n");
  179.   (void) fprintf(stderr,
  180.     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
  181.   (void) fprintf(stderr,"'-' for standard input or output.\n");
  182.   exit(1);
  183. }
  184.  
  185. /*
  186. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  187. %                                                                             %
  188. %                                                                             %
  189. %                                                                             %
  190. %    M a i n                                                                  %
  191. %                                                                             %
  192. %                                                                             %
  193. %                                                                             %
  194. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  195. %
  196. %
  197. */
  198. int main(argc,argv)
  199. int
  200.   argc;
  201.  
  202. char
  203.   **argv;
  204. {
  205.   char
  206.     *border_color,
  207.     *colormap_filename,
  208.     *comment,
  209.     *density,
  210.     *font,
  211.     *gamma,
  212.     *image_geometry,
  213.     *label,
  214.     *option,
  215.     *page_geometry,
  216.     *server_name,
  217.     *undercolor_geometry;
  218.  
  219.   Image
  220.     **images;
  221.  
  222.   ImageInfo
  223.     image_info;
  224.  
  225.   int
  226.     flags,
  227.     i,
  228.     p,
  229.     q,
  230.     x,
  231.     y;
  232.  
  233.   unsigned int
  234.     colorspace,
  235.     compression,
  236.     dither,
  237.     height,
  238.     image_number,
  239.     interlace,
  240.     maximum_images,
  241.     monochrome,
  242.     number_colors,
  243.     quality,
  244.     scene,
  245.     tree_depth,
  246.     verbose,
  247.     width;
  248.  
  249.   /*
  250.     Display usage profile if there are no command line arguments.
  251.   */
  252.   client_name=(*argv);
  253.   if (argc < 2)
  254.     Usage();
  255.   /*
  256.     Set defaults.
  257.   */
  258.   border_color=(char *) NULL;
  259.   colormap_filename=(char *) NULL;
  260.   colorspace=RGBColorspace;
  261.   comment=(char *) NULL;
  262.   compression=UndefinedCompression;
  263.   density=(char *) NULL;
  264.   dither=False;
  265.   font=(char *) NULL;
  266.   gamma=(char *) NULL;
  267.   image_geometry=(char *) NULL;
  268.   interlace=NoneInterlace;
  269.   label=(char *) NULL;
  270.   monochrome=False;
  271.   number_colors=0;
  272.   quality=85;
  273.   page_geometry=(char *) NULL;
  274.   server_name=(char *) NULL;
  275.   scene=0;
  276.   tree_depth=0;
  277.   undercolor_geometry=(char *) NULL;
  278.   verbose=False;
  279.   maximum_images=MaxTextLength;
  280.   images=(Image **) malloc(maximum_images*sizeof(Image *));
  281.   if (images == (Image **) NULL)
  282.     Error("Unable to mogrify images","Memory allocation failed");
  283.   /*
  284.     Parse command line.
  285.   */
  286.   image_number=0;
  287.   p=1;
  288.   for (i=1; i < argc; i++)
  289.   {
  290.     option=argv[i];
  291.     if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  292.       switch (*(option+1))
  293.       {
  294.         case 'b':
  295.         {
  296.           if (strncmp("border",option+1,7) == 0)
  297.             {
  298.               if (*option == '-')
  299.                 {
  300.                   i++;
  301.                   if (i == argc)
  302.                     Error("Missing geometry on -border",(char *) NULL);
  303.                 }
  304.               break;
  305.             }
  306.           if (strncmp("bordercolor",option+1,7) == 0)
  307.             {
  308.               border_color=(char *) NULL;
  309.               if (*option == '-')
  310.                 {
  311.                   i++;
  312.                   if (i == argc)
  313.                     Error("Missing color on -bordercolor",(char *) NULL);
  314.                   border_color=argv[i];
  315.                 }
  316.               break;
  317.             }
  318.           Error("Unrecognized option",option);
  319.           break;
  320.         }
  321.         case 'c':
  322.         {
  323.           if (strncmp("clip",option+1,2) == 0)
  324.             {
  325.               if (*option == '-')
  326.                 {
  327.                   i++;
  328.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  329.                     Error("Missing geometry on -clip",(char *) NULL);
  330.                 }
  331.               break;
  332.             }
  333.           if (strncmp("colormap",option+1,7) == 0)
  334.             {
  335.               colormap_filename=(char *) NULL;
  336.               if (*option == '-')
  337.                 {
  338.                   i++;
  339.                   if (i == argc)
  340.                     Error("Missing file name on -colormap",(char *) NULL);
  341.                   colormap_filename=argv[i];
  342.                 }
  343.               break;
  344.             }
  345.           if (strncmp("colors",option+1,7) == 0)
  346.             {
  347.               number_colors=0;
  348.               if (*option == '-')
  349.                 {
  350.                   i++;
  351.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  352.                     Error("Missing colors on -colors",(char *) NULL);
  353.                   number_colors=atoi(argv[i]);
  354.                 }
  355.               break;
  356.             }
  357.           if (strncmp("colorspace",option+1,7) == 0)
  358.             {
  359.               colorspace=RGBColorspace;
  360.               if (*option == '-')
  361.                 {
  362.                   i++;
  363.                   if (i == argc)
  364.                     Error("Missing type on -colorspace",(char *) NULL);
  365.                   option=argv[i];
  366.                   colorspace=UndefinedColorspace;
  367.                   if (Latin1Compare("gray",option) == 0)
  368.                     {
  369.                       colorspace=GRAYColorspace;
  370.                       number_colors=256;
  371.                       tree_depth=8;
  372.                     }
  373.                   if (Latin1Compare("ohta",option) == 0)
  374.                     colorspace=OHTAColorspace;
  375.                   if (Latin1Compare("rgb",option) == 0)
  376.                     colorspace=RGBColorspace;
  377.                   if (Latin1Compare("xyz",option) == 0)
  378.                     colorspace=XYZColorspace;
  379.                   if (Latin1Compare("ycbcr",option) == 0)
  380.                     colorspace=YCbCrColorspace;
  381.                   if (Latin1Compare("yiq",option) == 0)
  382.                     colorspace=YIQColorspace;
  383.                   if (Latin1Compare("yuv",option) == 0)
  384.                     colorspace=YUVColorspace;
  385.                   if (colorspace == UndefinedColorspace)
  386.                     Error("Invalid colorspace type on -colorspace",option);
  387.                 }
  388.               break;
  389.             }
  390.           if (strncmp("comment",option+1,4) == 0)
  391.             {
  392.               comment=(char *) NULL;
  393.               if (*option == '-')
  394.                 {
  395.                   i++;
  396.                   if (i == argc)
  397.                     Error("Missing comment on -comment",(char *) NULL);
  398.                   comment=argv[i];
  399.                 }
  400.               break;
  401.             }
  402.           if (strncmp("compress",option+1,3) == 0)
  403.             {
  404.               compression=NoCompression;
  405.               if (*option == '-')
  406.                 {
  407.                   i++;
  408.                   if (i == argc)
  409.                     Error("Missing type on -compress",(char *) NULL);
  410.                   option=argv[i];
  411.                   if (Latin1Compare("runlengthencoded",option) == 0)
  412.                     compression=RunlengthEncodedCompression;
  413.                   else
  414.                     if (Latin1Compare("qencoded",option) == 0)
  415.                       compression=QEncodedCompression;
  416.                     else
  417.                       Error("Invalid compression type on -compress",option);
  418.                 }
  419.               break;
  420.             }
  421.           Error("Unrecognized option",option);
  422.           break;
  423.         }
  424.         case 'd':
  425.         {
  426.           if (strncmp("density",option+1,3) == 0)
  427.             {
  428.               density=(char *) NULL;
  429.               if (*option == '-')
  430.                 {
  431.                   i++;
  432.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  433.                     Error("Missing geometry on -density",(char *) NULL);
  434.                   density=argv[i];
  435.                 }
  436.               break;
  437.             }
  438.           if (strncmp("display",option+1,3) == 0)
  439.             {
  440.               server_name=(char *) NULL;
  441.               if (*option == '-')
  442.                 {
  443.                   i++;
  444.                   if (i == argc)
  445.                     Error("Missing server name on -display",(char *) NULL);
  446.                   server_name=argv[i];
  447.                 }
  448.               break;
  449.             }
  450.           if (strncmp("dither",option+1,3) == 0)
  451.             {
  452.               dither=(*option == '-');
  453.               break;
  454.             }
  455.           Error("Unrecognized option",option);
  456.           break;
  457.         }
  458.         case 'e':
  459.         {
  460.           if (strncmp("enhance",option+1,1) == 0)
  461.             break;
  462.           Error("Unrecognized option",option);
  463.           break;
  464.         }
  465.         case 'f':
  466.         {
  467.           font=(char *) NULL;
  468.           if (*option == '-')
  469.             {
  470.               i++;
  471.               if (i == argc)
  472.                 Error("Missing font name on -font",(char *) NULL);
  473.               font=argv[i];
  474.             }
  475.           break;
  476.         }
  477.         case 'g':
  478.         {
  479.           if (strncmp("gamma",option+1,2) == 0)
  480.             {
  481.               gamma=(char *) NULL;
  482.               if (*option == '-')
  483.                 {
  484.                   i++;
  485.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  486.                     Error("Missing value on -gamma",(char *) NULL);
  487.                   gamma=argv[i];
  488.                 }
  489.               break;
  490.             }
  491.           if (strncmp("geometry",option+1,2) == 0)
  492.             {
  493.               image_geometry=(char *) NULL;
  494.               if (*option == '-')
  495.                 {
  496.                   i++;
  497.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  498.                     Error("Missing geometry on -geometry",(char *) NULL);
  499.                   image_geometry=argv[i];
  500.                 }
  501.               break;
  502.             }
  503.           Error("Unrecognized option",option);
  504.           break;
  505.         }
  506.         case 'h':
  507.         {
  508.           if (strncmp("help",option+1,2) == 0)
  509.             {
  510.               Usage();
  511.               break;
  512.             }
  513.           Error("Unrecognized option",option);
  514.           break;
  515.         }
  516.         case 'i':
  517.         {
  518.           if (strncmp("interlace",option+1,3) == 0)
  519.             {
  520.               interlace=NoneInterlace;
  521.               if (*option == '-')
  522.                 {
  523.                   i++;
  524.                   if (i == argc)
  525.                     Error("Missing type on -interlace",(char *) NULL);
  526.                   option=argv[i];
  527.                   interlace=UndefinedInterlace;
  528.                   if (Latin1Compare("none",option) == 0)
  529.                     interlace=NoneInterlace;
  530.                   if (Latin1Compare("line",option) == 0)
  531.                     interlace=LineInterlace;
  532.                   if (Latin1Compare("plane",option) == 0)
  533.                     interlace=PlaneInterlace;
  534.                   if (interlace == UndefinedInterlace)
  535.                     Error("Invalid interlace type on -interlace",option);
  536.                 }
  537.               break;
  538.             }
  539.           if (strncmp("inverse",option+1,3) == 0)
  540.             break;
  541.           Error("Unrecognized option",option);
  542.           break;
  543.         }
  544.         case 'l':
  545.         {
  546.           if (strncmp("label",option+1,2) == 0)
  547.             {
  548.               label=(char *) NULL;
  549.               if (*option == '-')
  550.                 {
  551.                   i++;
  552.                   if (i == argc)
  553.                     Error("Missing label name on -label",(char *) NULL);
  554.                   label=argv[i];
  555.                 }
  556.               break;
  557.             }
  558.           Error("Unrecognized option",option);
  559.           break;
  560.         }
  561.         case 'm':
  562.         {
  563.           monochrome=(*option == '-');
  564.           if (monochrome)
  565.             {
  566.               number_colors=2;
  567.               tree_depth=8;
  568.               colorspace=GRAYColorspace;
  569.             }
  570.           break;
  571.         }
  572.         case 'n':
  573.         {
  574.           if (strncmp("noise",option+1,3) == 0)
  575.             break;
  576.           if (strncmp("normalize",option+1,3) == 0)
  577.             break;
  578.           Error("Unrecognized option",option);
  579.           break;
  580.         }
  581.         case 'p':
  582.         {
  583.           if (strncmp("page",option+1,2) == 0)
  584.             {
  585.               page_geometry=(char *) NULL;
  586.               if (*option == '-')
  587.                 {
  588.                   i++;
  589.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  590.                     Error("Missing page geometry on -page",(char *) NULL);
  591.                   page_geometry=argv[i];
  592.                 }
  593.               break;
  594.             }
  595.           Error("Unrecognized option",option);
  596.           break;
  597.         }
  598.         case 'q':
  599.         {
  600.           i++;
  601.           if ((i == argc) || !sscanf(argv[i],"%d",&x))
  602.             Error("Missing quality on -quality",(char *) NULL);
  603.           quality=atoi(argv[i]);;
  604.           break;
  605.         }
  606.         case 'r':
  607.         {
  608.           if (strncmp("reflect",option+1,2) == 0)
  609.             break;
  610.           if (strncmp("roll",option+1,3) == 0)
  611.             {
  612.               if (*option == '-')
  613.                 {
  614.                   i++;
  615.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  616.                     Error("Missing geometry on -roll",(char *) NULL);
  617.                 }
  618.               break;
  619.             }
  620.           if (strncmp("rotate",option+1,3) == 0)
  621.             {
  622.               if (*option == '-')
  623.                 {
  624.                   i++;
  625.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  626.                     Error("Missing degrees on -rotate",(char *) NULL);
  627.                 }
  628.               break;
  629.             }
  630.           Error("Unrecognized option",option);
  631.           break;
  632.         }
  633.         case 's':
  634.         {
  635.           if (strncmp("scene",option+1,3) == 0)
  636.             {
  637.               scene=0;
  638.               if (*option == '-')
  639.                 {
  640.                   i++;
  641.                   if ((i == argc) || !sscanf(argv[i],"%d",&x))
  642.                     Error("Missing scene number on -scene",(char *) NULL);
  643.                   scene=atoi(argv[i]);
  644.                 }
  645.               break;
  646.             }
  647.           if (strncmp("shear",option+1,2) == 0)
  648.             {
  649.               if (*option == '-')
  650.                 {
  651.                   i++;
  652.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  653.                     Error("Missing shear geometry on -shear",(char *) NULL);
  654.                 }
  655.               break;
  656.             }
  657.           Error("Unrecognized option",option);
  658.           break;
  659.         }
  660.         case 't':
  661.         {
  662.           tree_depth=0;
  663.           if (*option == '-')
  664.             {
  665.               i++;
  666.               if ((i == argc) || !sscanf(argv[i],"%d",&x))
  667.                 Error("Missing depth on -treedepth",(char *) NULL);
  668.               tree_depth=atoi(argv[i]);
  669.             }
  670.           break;
  671.         }
  672.         case 'u':
  673.         {
  674.           if (strncmp("undercolor",option+1,2) == 0)
  675.             {
  676.               undercolor_geometry=(char *) NULL;
  677.               if (*option == '-')
  678.                 {
  679.                   i++;
  680.                   if ((i == argc) || !sscanf(argv[i],"%f",(float *) &x))
  681.                     Error("Missing undercolor geometry on -undercolor",
  682.                       (char *) NULL);
  683.                   undercolor_geometry=argv[i];
  684.                 }
  685.               break;
  686.             }
  687.           Error("Unrecognized option",option);
  688.           break;
  689.         }
  690.         case 'v':
  691.         {
  692.           verbose=(*option == '-');
  693.           break;
  694.         }
  695.         default:
  696.         {
  697.           Error("Unrecognized option",option);
  698.           break;
  699.         }
  700.       }
  701.     else
  702.       {
  703.         double
  704.           normalized_maximum_error,
  705.           normalized_mean_error;
  706.  
  707.         Image
  708.           *image,
  709.           info_image,
  710.           *next_image;
  711.  
  712.         time_t
  713.           start_time;
  714.  
  715.         unsigned int
  716.           mean_error_per_pixel;
  717.  
  718.         unsigned long
  719.           total_colors;
  720.  
  721.         /*
  722.           Option is a file name: begin by reading image from specified file.
  723.         */
  724.         start_time=time((time_t *) NULL);
  725.         GetImageInfo(argv[i],&image_info);
  726.         image_info.server_name=server_name;
  727.         image_info.font=font;
  728.         image_info.geometry=image_geometry;
  729.         image_info.page=page_geometry;
  730.         image_info.density=density;
  731.         image_info.interlace=interlace;
  732.         image_info.monochrome=monochrome;
  733.         image_info.quality=quality;
  734.         image_info.verbose=verbose;
  735.         image_info.undercolor=undercolor_geometry;
  736.         image=ReadImage(&image_info);
  737.         if (image == (Image *) NULL)
  738.           if (*option == '-')
  739.             break;
  740.           else
  741.             continue;
  742.         do
  743.         {
  744.           info_image=(*image);
  745.           if (scene != 0)
  746.             image->scene=scene;
  747.           LabelImage(image,label);
  748.           if (comment != (char *) NULL)
  749.             CommentImage(image,comment);
  750.           total_colors=0;
  751.           /*
  752.             Transform image as defined by the image geometries.
  753.           */
  754.           for (q=p; q < i; q++)
  755.           {
  756.             option=argv[q];
  757.             if (strncmp("-border",option,8) == 0)
  758.               {
  759.                 Image
  760.                   *bordered_image;
  761.       
  762.                 ImageInfo
  763.                   border_info;
  764.       
  765.                 /*
  766.                   Surround image with a border of solid color.
  767.                 */
  768.                 q++;
  769.                 border_info=image_info;
  770.                 (void) strcpy(border_info.filename,"XC:");
  771.                 if (border_color != (char *) NULL)
  772.                   (void) strcat(border_info.filename,border_color);
  773.                 border_info.geometry="1x1";
  774.                 bordered_image=ReadImage(&border_info);
  775.                 if (bordered_image != (Image *) NULL)
  776.                   {
  777.                     ColorPacket
  778.                       border_color;
  779.       
  780.                     RectangleInfo
  781.                       border_info;
  782.       
  783.                     DestroyImage(bordered_image);
  784.                     border_info.width=0;
  785.                     border_info.height=0;
  786.                     border_info.x=0;
  787.                     border_info.y=0;
  788.                     flags=XParseGeometry(argv[q],&border_info.x,&border_info.y,
  789.                       &border_info.width,&border_info.height);
  790.                     if ((flags & HeightValue) == 0)
  791.                       border_info.height=border_info.width;
  792.                     border_color.red=bordered_image->pixels->red;
  793.                     border_color.green=bordered_image->pixels->green;
  794.                     border_color.blue=bordered_image->pixels->blue;
  795.                     bordered_image=BorderImage(image,&border_info,&border_color,
  796.                       &border_color);
  797.                     if (bordered_image != (Image *) NULL)
  798.                       {
  799.                         DestroyImage(image);
  800.                         bordered_image->class=DirectClass;
  801.                         image=bordered_image;
  802.                       }
  803.                   }
  804.               }
  805.             if (strncmp("-clip",option,3) == 0)
  806.               TransformImage(&image,argv[++q],(char *) NULL);
  807.             if (strncmp("-enhance",option,2) == 0)
  808.               {
  809.                 Image
  810.                   *enhanced_image;
  811.       
  812.                 /*
  813.                   Enhance image.
  814.                 */
  815.                 enhanced_image=EnhanceImage(image);
  816.                 if (enhanced_image != (Image *) NULL)
  817.                   {
  818.                     DestroyImage(image);
  819.                     image=enhanced_image;
  820.                   }
  821.               }
  822.             if (strncmp("-gamma",option,3) == 0)
  823.               GammaImage(image,argv[++q]);
  824.             if (strncmp("-geometry",option,4) == 0)
  825.               TransformImage(&image,(char *) NULL,argv[++q]);
  826.             if (strncmp("-inverse",option,4) == 0)
  827.               InverseImage(image);
  828.             if (strncmp("-noise",option,4) == 0)
  829.               {
  830.                 Image
  831.                   *noisy_image;
  832.       
  833.                 /*
  834.                   Reduce noise in image.
  835.                 */
  836.                 noisy_image=NoisyImage(image);
  837.                 if (noisy_image != (Image *) NULL)
  838.                   {
  839.                     DestroyImage(image);
  840.                     image=noisy_image;
  841.                   }
  842.               }
  843.             if (strncmp("-normalize",option,4) == 0)
  844.               NormalizeImage(image);
  845.             if (strncmp("-reflect",option,3) == 0)
  846.               {
  847.                 Image
  848.                   *reflected_image;
  849.       
  850.                 /*
  851.                   Reverse image scanlines.
  852.                 */
  853.                 reflected_image=ReflectImage(image);
  854.                 if (reflected_image != (Image *) NULL)
  855.                   {
  856.                     DestroyImage(image);
  857.                     image=reflected_image;
  858.                   }
  859.               }
  860.             if (strncmp("-roll",option,4) == 0)
  861.               {
  862.                 Image
  863.                   *rolled_image;
  864.       
  865.                 /*
  866.                   Roll image.
  867.                 */
  868.                 x=0;
  869.                 y=0;
  870.                 flags=XParseGeometry(argv[++q],&x,&y,&width,&height);
  871.                 rolled_image=RollImage(image,x,y);
  872.                 if (rolled_image != (Image *) NULL)
  873.                   {
  874.                     DestroyImage(image);
  875.                     image=rolled_image;
  876.                   }
  877.               }
  878.             if (strncmp("-rotate",option,4) == 0)
  879.               {
  880.                 Image
  881.                   *rotated_image;
  882.       
  883.                 /*
  884.                   Rotate image.
  885.                 */
  886.                 rotated_image=RotateImage(image,(double) atof(argv[++q]),False);
  887.                 if (rotated_image != (Image *) NULL)
  888.                   {
  889.                     DestroyImage(image);
  890.                     image=rotated_image;
  891.                   }
  892.               }
  893.             if (strncmp("-shear",option,3) == 0)
  894.               {
  895.                 float
  896.                   x_shear,
  897.                   y_shear;
  898.       
  899.                 Image
  900.                   *sheared_image;
  901.       
  902.                 /*
  903.                   Shear image.
  904.                 */
  905.                 x_shear=0.0;
  906.                 y_shear=0.0;
  907.                 (void) sscanf(argv[++q],"%fx%f",&x_shear,&y_shear);
  908.                 sheared_image=ShearImage(image,x_shear,y_shear,False);
  909.                 if (sheared_image != (Image *) NULL)
  910.                   {
  911.                     DestroyImage(image);
  912.                     image=sheared_image;
  913.                   }
  914.             }
  915.           }
  916.           if (number_colors != 0)
  917.             {
  918.               /*
  919.                 Reduce the number of colors in the image.
  920.               */
  921.               if ((image->class == DirectClass) ||
  922.                   (image->colors > number_colors) ||
  923.                   (colorspace == GRAYColorspace))
  924.                 QuantizeImage(image,number_colors,tree_depth,dither,colorspace,
  925.                   True);
  926.               if (verbose)
  927.                 {
  928.                   /*
  929.                     Measure quantization error.
  930.                   */
  931.                   QuantizationError(image,&mean_error_per_pixel,
  932.                     &normalized_mean_error,&normalized_maximum_error);
  933.                   total_colors=NumberColors(image,(FILE *) NULL);
  934.                 }
  935.               SyncImage(image);
  936.             }
  937.           if (verbose)
  938.             {
  939.               /*
  940.                 Display detailed info about the image.
  941.               */
  942.               (void) fprintf(stderr,"[%u] %s",
  943.                 image->scene == 0 ? image_number : image->scene,
  944.                 info_image.filename);
  945.               (void) fprintf(stderr," %ux%u",info_image.columns,
  946.                 info_image.rows);
  947.               if ((info_image.columns != image->columns) ||
  948.                   (info_image.rows != image->rows))
  949.                 (void) fprintf(stderr,"=>%ux%u",image->columns,image->rows);
  950.               if (image->class == DirectClass)
  951.                 (void) fprintf(stderr," DirectClass");
  952.               else
  953.                 if (total_colors == 0)
  954.                   (void) fprintf(stderr," PseudoClass %uc",image->colors);
  955.                 else
  956.                   {
  957.                     (void) fprintf(stderr," PseudoClass %lu=>%uc",total_colors,
  958.                       image->colors);
  959.                     (void) fprintf(stderr," %u/%.6f/%.6fe",mean_error_per_pixel,
  960.                       normalized_mean_error,normalized_maximum_error);
  961.                   }
  962.               (void) fprintf(stderr," %s %lds\n",image->magick,
  963.                 time((time_t *) NULL)-start_time+1);
  964.             }
  965.           if (compression != UndefinedCompression)
  966.             image->compression=compression;
  967.           else
  968.             image->compression=info_image.compression;
  969.           if (number_colors == 0)
  970.             (void) WriteImage(&image_info,image);
  971.           if (image_number == maximum_images)
  972.             {
  973.               /*
  974.                 Increase size of images array.
  975.               */
  976.               maximum_images<<=1;
  977.               images=(Image **)
  978.                 realloc((char *) images,maximum_images*sizeof(Image *));
  979.               if (images == (Image **) NULL)
  980.                 Error("Unable to mogrify images","Memory allocation failed");
  981.             }
  982.           images[image_number++]=image;
  983.           next_image=image->next;
  984.           if (next_image != (Image *) NULL)
  985.             image=next_image;
  986.         } while (next_image != (Image *) NULL);
  987.         if (number_colors == 0)
  988.           DestroyImages(image);
  989.         p=i+1;
  990.       }
  991.     }
  992.   if (image_number == 0)
  993.     Error("Missing an image file name",(char *) NULL);
  994.   if (number_colors != 0)
  995.     {
  996.       Image
  997.         *colormap_image;
  998.  
  999.       /*
  1000.         Global colormap option;  reduce colors then write image.
  1001.       */
  1002.       colormap_image=(Image *) NULL;
  1003.       if (colormap_filename != (char *) NULL)
  1004.         {
  1005.           (void) strcpy(image_info.filename,colormap_filename);
  1006.           colormap_image=ReadImage(&image_info);
  1007.           if (colormap_image == (Image *) NULL)
  1008.             Error("Unable to mogrify images","cannot read image colormap");
  1009.         }
  1010.       maximum_images=image_number;
  1011.       QuantizeImages(images,maximum_images,colormap_image,number_colors,
  1012.         tree_depth,dither,colorspace,True);
  1013.       if (colormap_image != (Image *) NULL)
  1014.         DestroyImage(colormap_image);
  1015.       for (image_number=0; image_number < maximum_images; image_number++)
  1016.       {
  1017.         (void) WriteImage(&image_info,images[image_number]);
  1018.         DestroyImage(images[image_number]);
  1019.       }
  1020.     }
  1021.   (void) free((char *) images);
  1022.   return(False);
  1023. }
  1024.